package org.tissou.client.Panel_Premier.operations_tab.Operations;

import org.tissou.client.Services.*;
import org.tissou.client.widgets.Label_MessageInformation;
import com.google.gwt.user.client.ui.*;
import com.google.gwt.user.client.rpc.AsyncCallback;
import com.google.gwt.user.datepicker.client.DateBox;
import com.google.gwt.event.dom.client.KeyPressEvent;
import com.google.gwt.event.dom.client.KeyPressHandler;
import com.google.gwt.i18n.client.DateTimeFormat;

import java.util.Date;
import java.util.List;
import java.util.ArrayList;


/**
 * Created by IntelliJ IDEA.
 * User: Claire
 * Date: 03-Mar-2009
 * Time: 21:09:34
 * To change this template use File | Settings | File Templates.
 */
public class Operation_AchatRecette extends Operation_Base {
  DockPanel panel_type = new DockPanel();
  DockPanel panel_date = new DockPanel();
  DockPanel panel_libelle = new DockPanel();
  DockPanel panel_somme = new DockPanel();
  DockPanel panel_categories = new DockPanel();
  DockPanel panel_comptes = new DockPanel();

  DockPanel panel_dettes = new DockPanel();

  ArbreDeCategories categories = new ArbreDeCategories();
  ArbreDeComptes comptes = new ArbreDeComptes(InformationsGlobales.personneLoguee.getNom());
  ArbreDeProprietaires proprietaires = new ArbreDeProprietaires();
  RadioButton achat = new RadioButton("choix2", "Achat");
  RadioButton recette = new RadioButton("choix2", "Recette");
  TextBox libelle = new TextBox();
  Label libelle_Label = new Label("Libelle: ");
  TextBox somme = new TextBox();
  Label somme_Label = new Label("Somme: ");
  CheckBox verifie = new CheckBox("Verifie?");

  Grid tableDette = new Grid();
  List<ProprietaireInfos> proprietaires_dettes = new ArrayList<ProprietaireInfos>();
  
  Boolean mode_dette_autocalcule = true;
  List<TextBox> textbox_dans_autocalcul = new ArrayList<TextBox>();
  
  List<TextBox> somme_dettes = new ArrayList<TextBox>();
  int noproprietaires = 0;

  Button ok = new Button();

  AsyncCallback<List<ProprietaireInfos>> chargeageCallback = new AsyncCallback<List<ProprietaireInfos>>() {

    public void onFailure(Throwable caught) {
      MessageErreurServeur("Erreur mec. Arbre proprietaire non charge." + caught.getMessage());
      throw new MonException("Erreur mec. Arbre proprietaire non charge." + caught.getMessage());
    }

    public void onSuccess(List<ProprietaireInfos> result) {

      result.remove(InformationsGlobales.personneLoguee);
      proprietaires_dettes = result;
      noproprietaires =  proprietaires_dettes.size();
      tableDette.resize(noproprietaires+1, 2);

      for (int i=0; i<noproprietaires; i++){
        TextBox textbox_dette_somme = new TextBox();
        somme_dettes.add(textbox_dette_somme);
        tableDette.setWidget(i+1,1,textbox_dette_somme);
        TextBox_SommeDette_SetAction(textbox_dette_somme);
        Label nomproprietaire = new Label(proprietaires_dettes.get(i).getNom());
        tableDette.setWidget(i+1,0,nomproprietaire);
      }
    }
  };

  protected void MiseEnPlaceParametresWidgets(){
    ok.setText("OK");
    datePicker.setFormat(new DateBox.DefaultFormat(DateTimeFormat.getFormat("dd/MM/yyyy")));
    datePicker.setValue(new Date());
    EnsemblePropriosService.App.getInstance().donnerListeProprietaires(chargeageCallback);
  }

  protected void MiseEnPlaceStyles(){
    categories.addStyleName("defaultstyle");
    comptes.addStyleName("defaultstyle");
    datePicker.addStyleName("defaultstyle");
    verifie.addStyleName("dockPanelcellulesimple");
    panel_date.addStyleName("dockPanelcellulesimple");
    panel_libelle.addStyleName("dockPanelcellulesimple");
    panel_somme.addStyleName("dockPanelcellulesimple");
    panel_type.addStyleName("dockPanelcellulesimple");
    panel_dettes.addStyleName("dockPanelDettes");
  }

  protected void MiseEnPlaceParametresPanel(){
    panel_type.add(achat,DockPanel.WEST);
    panel_type.add(recette,DockPanel.WEST);
    panel_date.add(date_Label,DockPanel.WEST);
    panel_date.add(datePicker, DockPanel.WEST);
    panel_libelle.add(libelle_Label,DockPanel.WEST);
    panel_libelle.add(libelle,DockPanel.WEST);
    panel_somme.add(somme_Label,DockPanel.WEST);
    panel_somme.add(somme,DockPanel.WEST);
    panel_dettes.add(tableDette, DockPanel.WEST);
    panel_comptes.add(comptes, DockPanel.WEST);
    panel_comptes.addStyleName("dockPanelProprioComptes");
    panel_categories.add(categories, DockPanel.WEST);
    panel_categories.addStyleName("dockPanelCategories");
    panel_somme.add(ok, DockPanel.SOUTH);
  }

  protected void MiseEnPlaceActions(){

    ok.addClickListener(new ClickListener(){
      public void onClick(Widget sender) {
        EnvoyerInformationServeur(FormerParametresOperation());
      }
    });

    comptes.addTreeListener(new TreeListener(){
      public void onTreeItemSelected(TreeItem item) {
        DonnerCompte(item);
      }

      public void onTreeItemStateChanged(TreeItem item) {
        
      }
    });

  }

  public Parametres FormerParametresOperation(){
    Parametres parametres;
    if(achat.isChecked()){
/*
Operation_Depense:
  Date Date = date;
  Boolean Verifie = verifie;
  OperationFactoryInfos.TypeOperation Typeoperation = OPERATION_DEPENSE;

  List<CategorieInfos> Categories = categorie selectionnee dans l'arbre
  List<ProprietaireInfos> Proprietaires = void;
  List<Compte> Comptes = Compte concerne;
  List<String> Libelles = new ArrayList<String>() = libelle;
  List<Dette> Dettes = new ArrayList<Dette>() = dettes (Crediteur, Debiteur, Somme due)
 (pas de restriction de nombre);
  List<MonnaieInfos> Monnaies = new ArrayList<MonnaieInfos>() = void;
  List<Float> Sommes = new ArrayList<Float>() = somme concernee;

*/
/*
 Regarde petite Clairette, comment j'ai gere.
       Tu peux utiliser ce truc la, ca a l'air pas mal pas mal
       Va voir la pour plus d'infos : http://code.google.com/p/gwt-datepicker/wiki/HowToUse
       Bisous bisous j'espere que ca t'avancera bien pour le pub !
*/
      Float somme_depensee_moins_sommes_due=new Float(0);
      
      parametres = new Parametres(getDate(), verifie.isChecked(), OperationFactoryInfos.TypeOperation.OPERATION_DEPENSE);

      try{parametres.ajouterCategorie(categories.donneLaCategorieSelectionnee());
      } catch (MonException e){
        message_information.setMessage(Label_MessageInformation.Etat.MAUVAISEENTREE, e.getMessage());
        throw new MonException(e.getMessage());
      }

      try{parametres.ajouterCompte(comptes.donneLeCompteSelectionne());
      } catch(MonException e){
        message_information.setMessage(Label_MessageInformation.Etat.MAUVAISEENTREE, e.getMessage());
        throw e;
      }
      parametres.ajouterLibelle(libelle.getText());
      try {
        Float s = Float.valueOf(somme.getText().trim());
        parametres.ajouterSomme(s);
        somme_depensee_moins_sommes_due=somme_depensee_moins_sommes_due+s;
      } catch (NumberFormatException nfe) {
        MessageErreurEntree("La somme n'a pas ete rentree correctement. L'operation n'a pas ete entree.");
        throw new MonException("NumberFormatException: " + nfe.getMessage());
      }

      for (int i = 0; i<noproprietaires; i++){
        Dette d;
        ProprietaireInfos crediteur1 = InformationsGlobales.personneLoguee;
        ProprietaireInfos debiteur1 = proprietaires_dettes.get(i);
        TextBox t = (TextBox)  tableDette.getWidget(i+1,1);
        if (!t.getText().equals("")){
          Float sommedue1;
          try {
            sommedue1 = Float.valueOf(t.getText().trim());
            d = new Dette(crediteur1, debiteur1, sommedue1);
            somme_depensee_moins_sommes_due=somme_depensee_moins_sommes_due-sommedue1;
          } catch (NumberFormatException nfe) {
            MessageErreurEntree("Une somme de dette n'a pas ete rentree correctement. " +
                "L'operation n'a pas ete entree.");
            throw new RuntimeException("NumberFormatException: " + nfe.getMessage());
          }
          if(somme_depensee_moins_sommes_due<0){
        	MessageErreurEntree("La somme des sommes dues est superieure a la somme depensee !" +
        	  		"Impossible de rentrer l'operation.");
        	parametres = null;
          }
          else {
        	parametres.ajouterDette(d);
          }
        }
      }
    }

    else if (recette.isChecked()){
      /*
Operation_Recette
  Date Date = date;
  Boolean Verifie = verifie;
  OperationFactoryInfos.TypeOperation Typeoperation = OPERATION_DEPENSE;

  List<CategorieInfos> Categories = categorie selectionnee dans l'arbre
  List<ProprietaireInfos> Proprietaires = void;
  List<Compte> Comptes = Compte concerne;
  List<String> Libelles = new ArrayList<String>() = libelle;
  List<Dette> Dettes = new ArrayList<Dette>() = dettes (Crediteur, Debiteur, Somme due)
 (pas de restriction de nombre);
  List<MonnaieInfos> Monnaies = new ArrayList<MonnaieInfos>() = void;
  List<Float> Sommes = new ArrayList<Float>() = somme concernee;
*/
      Float somme_depensee_moins_sommes_due=new Float(0);
    	
      parametres = new Parametres(getDate(), verifie.isChecked(),
          OperationFactoryInfos.TypeOperation.OPERATION_RECETTE);
       try{parametres.ajouterCategorie(categories.donneLaCategorieSelectionnee());
      } catch (MonException e){
        message_information.setMessage(Label_MessageInformation.Etat.MAUVAISEENTREE, e.getMessage());
        throw new MonException(e.getMessage());
      }
      try{parametres.ajouterCompte(comptes.donneLeCompteSelectionne());
      } catch(MonException e){
        message_information.setMessage(Label_MessageInformation.Etat.MAUVAISEENTREE, e.getMessage());
        throw e;
      }
      parametres.ajouterLibelle(libelle.getText());
      try {
        Float s = Float.valueOf(somme.getText().trim());
        parametres.ajouterSomme(s);
        somme_depensee_moins_sommes_due=somme_depensee_moins_sommes_due+s;
      } catch (NumberFormatException nfe) {
        MessageErreurEntree("La somme n'a pas ete rentree correctement. L'operation n'a pas ete entree.");
      }

      for (int i = 0; i<noproprietaires; i++){
        Dette d;
        ProprietaireInfos debiteur1 = InformationsGlobales.personneLoguee;
        ProprietaireInfos crediteur1 = proprietaires_dettes.get(i);
        TextBox t = (TextBox)  tableDette.getWidget(i+1,1);
        if (!t.getText().equals("")){
          Float sommedue1;
          try {
            sommedue1 = Float.valueOf(t.getText().trim());
            d = new Dette(crediteur1, debiteur1, sommedue1);
            somme_depensee_moins_sommes_due=somme_depensee_moins_sommes_due-sommedue1;
          } catch (NumberFormatException nfe) {
            MessageErreurEntree("Une somme de dette n'a pas ete rentree correctement. " +
                "L'operation n'a pas ete entree.");
            throw new RuntimeException("NumberFormatException: " + nfe.getMessage());
          }
          if(somme_depensee_moins_sommes_due<0){
          	MessageErreurEntree("La somme des sommes dues est superieure a la somme recue !" +
          	  		"Impossible de rentrer l'operation.");
          	parametres = null;
          }
          else {
          	parametres.ajouterDette(d);
          }
        }
      }
    }

    else {
      MessageErreurEntree("Tu n'as pas dit si tu voulais une recette ou un achat");
      parametres = null;
    }

    return parametres;
  }
  
  private void TextBox_SommeDette_SetAction(TextBox t){
       t.addClickListener(new ClickListener() {
		
		@Override
		public void onClick(Widget sender) {
			if (mode_dette_autocalcule){
				if (((TextBox)sender).getText().equals("")){
					textbox_dans_autocalcul.add((TextBox)sender);
				}
				int n = textbox_dans_autocalcul.size()+1;
				Float s = Float.valueOf(somme.getText().trim());
				Float somme_due = s/n;
				((TextBox)sender).setText(somme_due.toString());
				for (int j = 0; j<noproprietaires; j++){	
					TextBox tt = (TextBox)  tableDette.getWidget(j+1,1);
					if (!tt.equals(sender)){
					    if (!tt.getText().equals("")){
					    	tt.setText(somme_due.toString());
					    }
					}
				}
				mode_dette_autocalcule=true;
			}
		}
	});
	    
      
    t.addKeyPressHandler(new KeyPressHandler() {
		
		@Override
		public void onKeyPress(KeyPressEvent event) {
			mode_dette_autocalcule=false;
		}
	});
    
  }
  
  @Override
  public void InitialiserValeurs() {
	  // Fonction appelée quand la transaction a été entrée avec succès dans la base de données.
	
	  // Permet de réintialiser différentes valeurs : le libellé, la somme totale, et les dettes.
	  	  
	  libelle.setText("");
	  somme.setText("");

	  for (int i = 0; i<noproprietaires; i++){
		  TextBox t = (TextBox)  tableDette.getWidget(i+1,1);
	      t.setText("");
	  }
	  
	  // On met aussi à zéro le décompte des personnes incluses dans une opération :
	  textbox_dans_autocalcul.clear();
	  
	  // On se remet en mode autocalcul :
	  mode_dette_autocalcule=true;
  	
  }

  protected void MiseEnPlacePanels(){
    principal.setVerticalAlignment(DockPanel.ALIGN_TOP);

    principal.add(message_information, DockPanel.NORTH);
    principal.setCellHeight(message_information, "40px");
    principal.add(panel_type, DockPanel.NORTH);
    principal.add(panel_categories, DockPanel.WEST);
    principal.add(panel_comptes, DockPanel.WEST);

    principal.add(panel_date, DockPanel.NORTH);
    principal.add(panel_libelle, DockPanel.NORTH);
    principal.add(verifie, DockPanel.NORTH);
    principal.add(panel_somme, DockPanel.NORTH);
    principal.add(panel_dettes, DockPanel.NORTH);
  }


}
